package cn.zou.core.util.luncene;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.TopFieldDocs;
import org.apache.lucene.search.highlight.Formatter;
import org.apache.lucene.search.highlight.Fragmenter;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.Scorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

import cn.zou.blog.entry.Article;

/**
 * 博客的索引工具类
 * @author zoujing
 *
 */
public class IndexUtils {
	private static Logger logger=Logger.getLogger(IndexUtils.class);
	//索引目录
	private static String path;
	//luncene版本 默认使用的是4.3
	private static Version LUNCENE_VERSION=Version.LUCENE_43;
	//分词
	private static Analyzer analyzer=new StandardAnalyzer(LUNCENE_VERSION);
	//
	private static IndexSearcher indexSeracher;
	//
	private static IndexWriter indexWriter;
	//
	private static long oldTime=new Date().getTime();
	//
	private static long timeofduration=60*60*2;
	//索引次数
	private static int indexNumber=0;
	/**
	 * 创建单个索引
	 */
	public static void IndexCreta(Document document){
		ArrayList<Document> list=new ArrayList<Document>();
		list.add(document);
		IndexCreat(list);
	}
	/**
	 * 创建索引
	 */
	public static void IndexCreat(List<Document> documents){
		try {
			Directory dirtctory=FSDirectory.open(new File(path));
			IndexWriter indexWriter = getIndexWriter(dirtctory);
			if(indexWriter==null){
				logger.error("获取indexWriter错误");
				return ;
			}
			for(Document doc:documents){
				
					indexWriter.addDocument(doc);	
			}
				indexWriter.commit();
				indexNumber++;
			
			
			indexWriter.close();
			dirtctory.close();
			setIndexWriter(null);
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			logger.error(e.getMessage());
		}
		
		
	}

	
	public static IndexWriter getIndexWriter(Directory dirtctory) throws IOException {
		if(indexWriter==null){
			if(indexWriter.isLocked(dirtctory)){
				//释放锁
				indexWriter.unlock(dirtctory);
			}
			
			indexWriter=new IndexWriter(dirtctory, getIndexWriterConfig());
		
			return indexWriter;
		};
		
		return indexWriter;
		
	}
	/**
	 * 索引查询
	 * @param filed
	 * @param txt
	 * @return
	 */
	public static List<Article> indexSerch(String txt,Sort sort,int pageNO,int pageSize,boolean isPaper,String... fileds){
		try {
			List<Article> list=new ArrayList<Article>();
			MultiFieldQueryParser queryParser=new MultiFieldQueryParser(LUNCENE_VERSION, fileds, analyzer);
			Query query = queryParser.parse(txt);
			IndexSearcher indexSeracher2 = getIndexSeracher();
			TopFieldDocs td = indexSeracher2.search(query, 100000, sort);
			for(int i=0;i<pageSize&&i<(td.totalHits-(pageNO*pageSize));i++){
				Document doc = indexSeracher2.doc(td.scoreDocs[i+(pageNO*pageSize)].doc);
				Article documentConversionBean = LunceneUtils.DocumentConversionBean(doc);
				String title = getHighlighted(doc,query,"title");
				documentConversionBean.setTitle(title==null?documentConversionBean.getTitle():title);
				
				documentConversionBean.setContent(isPaper?documentConversionBean.getContent():ContentPaper.conttentPaper(documentConversionBean.getContent()));
				list.add(documentConversionBean);
			}
			
			return list;
		} catch (Exception e) {
			// TODO 自动生成的 catch 块
			logger.error(e.getMessage());
		}
		return null;
	}
	/**
	 * 搜索结果高亮
	 * @param doc
	 * @param query
	 * @return
	 * @throws Exception 
	 * @throws IOException 
	 */
	private static String getHighlighted(Document doc,Query query,String field) throws IOException, Exception {
		Formatter format=new SimpleHTMLFormatter("<font color='red'>", "</font>");
		Scorer scorer = new QueryScorer(query);
		Highlighter highlighter = new Highlighter(format, scorer);
		Fragmenter fragmenter  = new SimpleFragmenter(10);
		highlighter.setTextFragmenter(fragmenter);
		String highlighterContent = highlighter.getBestFragment(analyzer,field,doc.get(field));
		
	 
		return highlighterContent;
	}

	/**
	 * 返回索引的数量的总数
	 * @return
	 * @throws IOException
	 */
	public static int indexSerchCount(String txt,String... fileds){
		try {
			List<Article> list=new ArrayList<Article>();
			MultiFieldQueryParser queryParser=new MultiFieldQueryParser(LUNCENE_VERSION, fileds, analyzer);
			Query query = queryParser.parse(txt);
			TopDocs td = getIndexSeracher().search(query,1000000);
			return td.scoreDocs.length;
			
		} catch (Exception e) {
			// TODO 自动生成的 catch 块
			logger.error(e.getMessage());
		}
		return 0;
	}
	public static IndexSearcher getIndexSeracher() throws IOException{
		if(new Date().getTime()-oldTime>=getTimeofduration()){
			indexSeracher=null;				
		}
		if(indexSeracher==null){
			DirectoryReader dr=DirectoryReader.open(FSDirectory.open(new File(path)));
			indexSeracher=new IndexSearcher(dr);
			return indexSeracher;
		}
		
		return indexSeracher;
	}
	private static boolean isOverdue() {
		
		return false;
	}
	
	public static Sort getSort(String filed) {
		Sort sort=new Sort(new SortField(filed, SortField.Type.INT, true));
		return sort;
	}

	private static  IndexWriterConfig getIndexWriterConfig() {
		// TODO 自动生成的方法存根
		IndexWriterConfig indexWriterConfig=new IndexWriterConfig(Version.LUCENE_43, analyzer);
		indexWriterConfig.setOpenMode(OpenMode.CREATE_OR_APPEND);
		return indexWriterConfig;
	}
	/**
	 * 更新索引
	 * @param doc
	 */
	public static void upadteIndex(Document doc){
		try {
			Directory open = FSDirectory.open(new File(path));
			IndexWriter indexWriter = getIndexWriter(open);
			indexWriter.updateDocument(new Term("id", doc.get("id")), doc);
			indexWriter.commit();
			indexWriter.close();
			setIndexWriter(null);
			open.close();
		} catch (IOException e) {
			logger.error("更新索引时候"+e.getMessage());
		}
	}
	/**
	 * 删除索引
	 * @param path
	 */
	public  static void deletIndex(String id){
		try {
			Directory open = FSDirectory.open(new File(path));
			IndexWriter indexWriter = getIndexWriter(open);
			indexWriter.deleteDocuments(new Term("id", id));
			indexWriter.commit();
			indexWriter.close();
			setIndexWriter(null);
			open.close();

		} catch (IOException e) {
			logger.error("删除索引时候"+e.getMessage());
		}
	}
	public static void setPath(String path) {
		IndexUtils.path = path;
	}
	public static void setLUNCENE_VERSION(Version lUNCENE_VERSION) {
		LUNCENE_VERSION = lUNCENE_VERSION;
	}
	public static void setAnalyzer(Analyzer analyzer) {
		IndexUtils.analyzer = analyzer;
	}
	public static long getTimeofduration() {
		return timeofduration;
	}
	public static void setTimeofduration(long timeofduration) {
		IndexUtils.timeofduration = timeofduration;
	}
	public static String getPath() {
		return path;
	}
	public static void setIndexWriter(IndexWriter indexWriter) {
		IndexUtils.indexWriter = indexWriter;
	}
	
	
}
